
//--------------------------------------------------------------------//
//     此代码由T4模板自动生成										  //
//	   生成时间 2020-06-22 10:26:00 	                              //
//	   描述：编号规则表
//--------------------------------------------------------------------//

using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Linq;
using Dapper;
using Newtonsoft.Json.Linq;
using RayD.Core;
using RayD.Repository;
using RayD.Repository.Entites.SystemModule;
using System;

namespace RayD.App.SystemModule
{
    public class CodeRuleApp
    {
        #region 构造函数注入
        private IRepository BaseRepository;
        public CodeRuleApp(IRepository repository)
        {
            this.BaseRepository = repository;
        }
        #endregion

        #region 获取数据

        /// <summary>
        /// 获取列表数据
        /// <summary>
        /// <param name=\"queryJson\">查询参数</param>
        /// <returns></returns>
        public IEnumerable<CodeRuleEntity> GetList(string queryJson)
        {
            var expression = LinqExtensions.True<CodeRuleEntity>();
            var queryParam = queryJson.ToJObject();
            return BaseRepository.IQueryable(expression).OrderByDescending(c => c.B_CreateDate);
        }

        /// <summary>
        /// 获取规则格式列表数据
        /// </summary>
        /// <param name="ruleId">编码规则主键</param>
        /// <returns></returns>
        [Caching]
        public virtual List<CodeRuleFormatEntity> GetFormatList(string ruleId)
        {
            return BaseRepository
                .FindList<CodeRuleFormatEntity>(c => c.B_RuleId.Equals(ruleId))
                .OrderBy(c => c.B_SortCode)
                .ToList();
        }

        #endregion

        #region 提交数据

        /// <summary>
        /// 保存实体数据（新增、修改）
        /// <summary>
        /// <param name="codeRuleEntity">规则实体</param>
        /// <param name="formatList">规则格式集合</param>
        /// <returns></returns>
        [RemoveCache]
        public virtual (bool, string) SaveForm(CodeRuleEntity codeRuleEntity, List<CodeRuleFormatEntity> formatList)
        {
            //字段验重
            if (ValidateExist(codeRuleEntity.B_RuleId, "B_Name", codeRuleEntity.B_Name)) return (false, "规则名称已存在！");
            if (ValidateExist(codeRuleEntity.B_RuleId, "B_EnCode", codeRuleEntity.B_EnCode)) return (false, "规则编码已存在！");
            var db = BaseRepository.BeginTrans();
            try
            {
                if (!codeRuleEntity.B_RuleId.IsEmpty())
                {
                    //编辑(Null、主键不会更改)
                    codeRuleEntity.Modify();
                    db.Update(codeRuleEntity);
                    //删除表体
                    db.Delete<CodeRuleFormatEntity>(c => c.B_RuleId.Equals(codeRuleEntity.B_RuleId));
                }
                else
                {
                    //新增
                    codeRuleEntity.Create();
                    db.Insert(codeRuleEntity);
                }
                //表体数据
                int i = 0;
                foreach (var item in formatList)
                {
                    item.Create();
                    item.B_RuleId = codeRuleEntity.B_RuleId;
                    item.B_SortCode = i;
                    db.Insert(item);
                    ++i;
                }
                db.Commit();
                return (true, "保存成功！");
            }
            catch (Exception)
            {
                db.Rollback();
                throw;
            }
        }
        /// <summary>
        /// 删除实体数据
        /// <summary>
        /// <param name="formEntity">数据实体</param>
        /// <returns></returns>
        [RemoveCache]
        public virtual (bool, string) DeleteForm(CodeRuleEntity formEntity)
        {
            var db = BaseRepository.BeginTrans();
            try
            {
                //删除表头
                db.Delete(formEntity);
                //删除表体
                db.Delete<CodeRuleFormatEntity>(c => c.B_RuleId.Equals(formEntity.B_RuleId));
                db.Delete<CodeRuleSeedEntity>(c => c.B_RuleId.Equals(formEntity.B_RuleId));
                db.Commit();
                return (true, "删除成功！");
            }
            catch (Exception)
            {
                db.Rollback();
                throw;
            }
        }

        #endregion

        #region 数据验证
        /// <summary>
        /// 验证字段值是否存在
        /// </summary>
        /// <param name="id">实体主键</param>
        /// <param name="field">字段名</param>
        /// <param name="value">字段值</param>
        /// <returns></returns>
        public bool ValidateExist(string id, string field, string value)
        {
            var expression = LinqExtensions.True<CodeRuleEntity>();
            if (!string.IsNullOrEmpty(id))
            {
                expression = expression.And(t => t.B_RuleId != id);
            }
            return this.BaseRepository.IQueryable(expression).Exist(field, value);
        }
        #endregion

        #region 编码处理        
        /// <summary>
        /// 获得指定模块编号
        /// </summary>
        /// <param name="enCode">编码</param>
        /// <returns>单据号</returns>
        public string GetCode(string enCode)
        {
            var db = this.BaseRepository.BeginTrans();
            try
            {
                string currentCode = "";    //当前编号
                string nextCode = "";//下一编号
                bool isOutTime = false;  //是否已过期

                CodeRuleEntity coderuleentity = db.FindEntity<CodeRuleEntity>(c => c.B_EnCode.Equals(enCode));
                if (coderuleentity != null)
                {
                    UserInfo userInfo = AuthenticationHelper.LoginUserInfo; //当前用户信息
                    int nowSerious = 0;                                     //当前流水
                    string dateFormatStr = "";                              //日期字符串格式
                    List<CodeRuleFormatEntity> codeRuleFormatList = this.GetFormatList(coderuleentity.B_RuleId);
                    foreach (CodeRuleFormatEntity codeRuleFormatEntity in codeRuleFormatList)
                    {
                        switch (codeRuleFormatEntity.B_ItemType.ToString())
                        {
                            //自定义项
                            case "0":
                                currentCode = currentCode + codeRuleFormatEntity.B_FormatStr;
                                nextCode = nextCode + codeRuleFormatEntity.B_FormatStr;
                                break;
                            //日期
                            case "1":
                                //日期字符串类型
                                dateFormatStr = codeRuleFormatEntity.B_FormatStr;
                                currentCode = currentCode + DateTime.Now.ToCstTime().ToString(codeRuleFormatEntity.B_FormatStr.Replace("m", "M"));
                                nextCode = nextCode + DateTime.Now.ToCstTime().ToString(codeRuleFormatEntity.B_FormatStr.Replace("m", "M"));
                                break;
                            //流水号
                            case "2":
                                #region 获取当前编号规则最大种子
                                CodeRuleSeedEntity maxSeed = db.FindEntity<CodeRuleSeedEntity>(c => c.B_RuleId.Equals(coderuleentity.B_RuleId));
                                if (maxSeed.IsEmpty())
                                {
                                    //说明没有种子，预插入一条种子
                                    maxSeed = new CodeRuleSeedEntity();
                                    maxSeed.B_SeedValue = codeRuleFormatEntity.B_InitValue ?? 1;
                                    maxSeed.B_RuleId = coderuleentity.B_RuleId;
                                    maxSeed.B_CreateDate = DateTime.Now.ToCstTime();
                                    maxSeed.B_CreateUserId = userInfo.userId;
                                    maxSeed.B_CreateUserName = userInfo.realName;
                                    maxSeed.B_ModifyDate = DateTime.Now.ToCstTime();
                                    maxSeed.B_ModifyUserId = userInfo.userId;
                                    maxSeed.B_ModifyUserName = userInfo.realName;
                                }
                                #endregion

                                #region 处理过期流水号归0
                                // 首先确定最大种子是否未归0的
                                if (dateFormatStr.Contains("dd"))
                                {
                                    if ((maxSeed.B_ModifyDate).ToDateString() != DateTime.Now.ToCstTime().ToString("yyyy-MM-dd"))
                                    {
                                        isOutTime = true;
                                        nowSerious = codeRuleFormatEntity.B_InitValue ?? 1;
                                        maxSeed.B_SeedValue = nowSerious + codeRuleFormatEntity.B_StepValue;
                                        maxSeed.B_ModifyDate = DateTime.Now.ToCstTime();
                                    }
                                }
                                else if (dateFormatStr.Contains("mm"))
                                {
                                    if (((DateTime)maxSeed.B_ModifyDate).ToString("yyyy-MM") != DateTime.Now.ToCstTime().ToString("yyyy-MM"))
                                    {
                                        isOutTime = true;
                                        nowSerious = codeRuleFormatEntity.B_InitValue ?? 1;
                                        maxSeed.B_SeedValue = nowSerious + codeRuleFormatEntity.B_StepValue;
                                        maxSeed.B_ModifyDate = DateTime.Now.ToCstTime();
                                    }
                                }
                                else if (dateFormatStr.Contains("yy"))
                                {
                                    if (((DateTime)maxSeed.B_ModifyDate).ToString("yyyy") != DateTime.Now.ToCstTime().ToString("yyyy"))
                                    {
                                        isOutTime = true;
                                        nowSerious = codeRuleFormatEntity.B_InitValue ?? 1;
                                        maxSeed.B_SeedValue = nowSerious + codeRuleFormatEntity.B_StepValue;
                                        maxSeed.B_ModifyDate = DateTime.Now.ToCstTime();
                                    }
                                }
                                #endregion

                                #region 保存编号规则种子
                                if (isOutTime)
                                {
                                    if (!maxSeed.B_RuleSeedId.IsEmpty())
                                    {
                                        //编辑(Null、主键不会更改)
                                        maxSeed.Modify();
                                        db.Update(maxSeed);
                                    }
                                    else
                                    {
                                        //新增
                                        maxSeed.Create();
                                        db.Insert(maxSeed);
                                    }
                                }
                                else
                                {
                                    nowSerious = (int)maxSeed.B_SeedValue;
                                    maxSeed.B_SeedValue += codeRuleFormatEntity.B_StepValue;
                                    if (!maxSeed.B_RuleSeedId.IsEmpty())
                                    {
                                        //编辑(Null、主键不会更改)
                                        maxSeed.Modify();
                                        db.Update(maxSeed);
                                    }
                                    else
                                    {
                                        //新增
                                        maxSeed.Create();
                                        db.Insert(maxSeed);
                                    }
                                }
                                #endregion

                                // 最大种子已经过期
                                string seriousStr = new string('0', (int)(codeRuleFormatEntity.B_FormatStr.Length - nowSerious.ToString().Length)) + nowSerious.ToString();
                                string NextSeriousStr = new string('0', (int)(codeRuleFormatEntity.B_FormatStr.Length - nowSerious.ToString().Length)) + maxSeed.B_SeedValue.ToString();
                                currentCode = currentCode + seriousStr;
                                nextCode = nextCode + NextSeriousStr;
                                break;
                            //部门编码
                            case "3":
                                DepartmentEntity departmentEntity = db.FindEntity<DepartmentEntity>(userInfo.departmentId);
                                currentCode = currentCode + departmentEntity.B_EnCode;
                                nextCode = nextCode + departmentEntity.B_EnCode;
                                break;
                            //组织架构编码
                            case "4":
                                ManaframeEntity manaEntity = db.FindEntity<ManaframeEntity>(userInfo.manaframeId);
                                currentCode = currentCode + manaEntity.B_EnCode;
                                nextCode = nextCode + manaEntity.B_EnCode;
                                break;
                            //用户编码（工号）
                            case "5":
                                currentCode = currentCode + userInfo.enCode;
                                nextCode = nextCode + userInfo.enCode;
                                break;
                            default:
                                break;
                        }
                    }
                    coderuleentity.B_NextNumber = nextCode;
                    coderuleentity.Modify();
                    db.Update(coderuleentity);
                }

                db.Commit();
                return currentCode;
            }
            catch (Exception)
            {
                db.Rollback();
                throw;
            }
        }
        #endregion
    }
}

